package com.luoye_lj.dogcontroller.log;

import android.annotation.SuppressLint;
import android.util.Log;

import com.luoye_lj.dogcontroller.util.DateUtil;
import com.luoye_lj.dogcontroller.util.EmailUtil;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.mail.internet.MimeUtility;

public class ArLog {
    private static final String TAG = ArLog.class.getSimpleName();
    /**
     * debug or not
     * when release, set debug 'false'
     */
    private static boolean debug = true;
    private static FileOutputStream fos=null;
    private static int lineCount=0;
    private static String logDir=null;
    private static final Object lock=new Object();
    public static void init(String path){
        if(path==null){
            return;
        }
        lineCount=0;
        logDir=path;
        try {
            @SuppressLint("SimpleDateFormat")
            SimpleDateFormat format = new SimpleDateFormat(
                    "yyyy_MM_dd_HH_mm_ss_SSS");// 用于格式化日期,作为日志文件名的一部分
            String timeStr=format.format(new Date());
            Log.i(TAG,path);
            synchronized (lock) {
                fos = new FileOutputStream(path + File.separator + "log_" + timeStr + ".txt");
            }
        } catch (FileNotFoundException e) {
            Log.e(TAG, e.getMessage());
        }
    }
    public static void close(){
        synchronized (lock) {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    Log.e(TAG, e.getMessage());
                }
                fos = null;
            }
        }
    }


    private ArLog() {

    }

    private static String getFunctionName() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        if(stackTrace.length<6){
            return null;
        }
        int stackOffset = 5; // 根据需要调整，直到获取到正确的行号
        String fileName=stackTrace[stackOffset].getFileName();
        String className=stackTrace[stackOffset].getClassName();
        String caller = stackTrace[stackOffset].getMethodName();
        int lineNumber = stackTrace[stackOffset].getLineNumber();
        @SuppressLint("DefaultLocale")
        String str=String.format("[%s %s %s.%s:%d] ", DateUtil.format(new Date()),fileName,className, caller, lineNumber);
        return str;
    }

    private static String createMessage(String msg) {
        String functionName = getFunctionName();
        String message = (functionName == null ? msg : (functionName + " - " + msg));
        return message;
    }

    private static synchronized void writeToFile(String msg){
        synchronized (lock) {
            if (fos != null) {
                try {
                    fos.write((msg + "\n").getBytes(StandardCharsets.UTF_8));
                    fos.flush();
                } catch (IOException e) {
                    Log.i(TAG, e.getMessage());
                }
                lineCount++;
                if (lineCount >= 50000) {
                    close();
                    init(logDir);
                }
            }
        }
    }

    /**
     * log.i
     */
    public static void i(String tag, String msg) {
        if (debug) {
            String message = createMessage(msg);
            Log.i(tag, message);
            writeToFile(message);
        }
    }

    /**
     * log.v
     */
    public static void v(String tag, String msg) {
        if (debug) {
            String message = createMessage(msg);
            Log.v(tag, message);
            writeToFile(message);
        }
    }

    /**
     * log.d
     */
    public static void d(String tag, String msg) {
        if (debug) {
            String message = createMessage(msg);
            Log.d(tag, message);
            writeToFile(message);
        }
    }

    /**
     * log.e
     */
    public static void e(String tag, String msg) {
        if (debug) {
            String message = createMessage(msg);
            Log.e(tag, message);
            writeToFile(message);
        }
    }
    /**
     * log.error
     */
    public static void error(String tag, Exception e){
        if(debug){
            StringBuffer sb = new StringBuffer();
            String name = getFunctionName();
            StackTraceElement[] sts = e.getStackTrace();

            if (name != null) {
                sb.append(name+" - "+e+"\r\n");
            } else {
                sb.append(e+"\r\n");
            }
            if (sts != null) {
                for (StackTraceElement st:sts) {
                    if (st != null) {
                        sb.append("[ "+st.getFileName()+":"+st.getLineNumber()+" ]\r\n");
                    }
                }
            }
            Log.e(tag,sb.toString());
            writeToFile(sb.toString());
        }
    }
    /**
     * log.w
     */
    public static void w(String tag, String msg) {
        if (debug) {
            String message = createMessage(msg);
            Log.w(tag, message);
            writeToFile(message);
        }
    }

    /**
     * set debug false
     */
    public static void setDebug(boolean d) {
        debug = d;
    }


    public static interface CommonPostCallback{
        void ok();
        void error(String errMsg);
    }

    public static synchronized void sendEmail(CommonPostCallback commonPostCallback){
        close();
        new Thread(new Runnable() {
            @Override
            public void run() {
                MimeUtility.mimeCharset("UTF-8");
                File file=new File(logDir);
                File[] files = file.listFiles();
                List<String> filePaths=new ArrayList<>();
                for(File f:files) {
                    String fpath=f.getAbsolutePath();
                    Log.i(TAG, "logFilePath: " + fpath);
                    if (!fpath.endsWith(".sent")) {
                        filePaths.add(fpath);
                    } else {
                        f.delete();
                    }
                }
                init(logDir);
                Collections.sort(filePaths);
                // 文件数量限制20
                List<String> sendFilePaths=new ArrayList<>();
                int size=filePaths.size();
                for(int i=0;i<20;i++){
                    int index=size-1-i;
                    if(index<0){
                        break;
                    }
                    sendFilePaths.add(filePaths.get(index));
                }

                Log.i(TAG,"size:"+size+",sendFiles->"+sendFilePaths.toString());

                EmailUtil.sendFile("日志","日志",sendFilePaths,"397035160@qq.com");
//                EmailUtil.sendTxt("log","hello","397035160@qq.com");
                commonPostCallback.ok();
                // 备份日志
                for(String fp:filePaths){
                    new File(fp).renameTo(new File(fp+".sent"));
                }
            }
        }).start();
    }
}